﻿using System;
using System.IO;
using System.Security.AccessControl;
using System.Web;

namespace SilverlightUpload.Web
{
    /// <summary>
    /// DataHandler 的摘要说明
    /// </summary>
    public class DataHandler : IHttpHandler
    {
        private HttpContext _context;
        private TextWriter logWrite;
        public void ProcessRequest(HttpContext context)
        {
            _context = context;
            using (logWrite = new StreamWriter(_context.Server.MapPath("~/ClientBin/Images/" + "log.txt"), true, System.Text.Encoding.UTF8))
            {
                try
                {
                    BinaryReader br = new BinaryReader(context.Request.InputStream);
                    int itemCount = br.ReadInt32();
                    logWrite.WriteLine(string.Format("New transfer start at {0}.",DateTime.Now));
                    logWrite.WriteLine(string.Format("Total Files:{0}", itemCount));
                    for (int i = 0; i < itemCount; i++)
                    {
                        PicItemBase item = new PicItemBase();
                        ReadPicInfo(br, ref item);

                    }
                }catch(Exception e){logWrite.WriteLine("An Error occured."+e.Message);}

            }
        }

        private void SaveImage(Stream stream, FileStream fs, long ilength)
        {
            long remainLength = ilength;
            const int blockSize = 4096;
            byte[] buffer = new byte[blockSize];
            int count = 0;
            while (remainLength > 0)
            {
                int buffersize = (remainLength < blockSize) ? (int)remainLength : blockSize;
                int bytesRead = stream.Read(buffer, 0, buffersize);
                fs.Write(buffer, 0, bytesRead);
                //logWrite.WriteLine("Try to read:{0}, actruely read {1}",buffersize,bytesRead);
                remainLength -= blockSize;
                count++;
            }
            //logWrite.WriteLine(string.Format("Total read {0} times.",count));
        } 

        private void ReadPicInfo(BinaryReader br, ref PicItemBase item)
        {
            int idesc = br.ReadInt32();
            item.Description = System.Text.Encoding.UTF8.GetString(br.ReadBytes(idesc), 0, idesc);
            int iperson = br.ReadInt32();
            item.Person = System.Text.Encoding.UTF8.GetString(br.ReadBytes(iperson), 0, iperson);
            item.TakeDate = DateTime.FromOADate(br.ReadDouble());
            long ilength = br.ReadInt64();
            logWrite.WriteLine(string.Format("Description:{0},Person:{1},Date:{2}",  item.Description, item.Person, item.TakeDate));
            logWrite.WriteLine(string.Format("Length:{0}",ilength));
          
            
            
            #region Save Image
            string filename;
            while (true)
            {
                filename = _context.Server.MapPath("~/ClientBin/Images/") + DateTime.Now.ToString("yyyyMMddhhmmss") + ".jpg";
                if (!File.Exists(filename)) break;
                System.Threading.Thread.Sleep(300);
            }
            logWrite.WriteLine(string.Format("Save file {0}",filename));
            using (FileStream fs = File.Create(filename))
            {
                SaveImage(br.BaseStream, fs, ilength);
            }

            #endregion Save Image

        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }


        public class PicItemBase
        {
            private FileInfo file;
            public FileInfo File
            {
                get { return file; }
                set { file = value; }
            }

            private DateTime takeDate = DateTime.Now;
            public DateTime TakeDate
            {
                get { return takeDate; }
                set { takeDate = value; }
            }

            private string person = "";
            public string Person
            {
                get { return person; }
                set { person = value; }
            }

            private string description = "";
            public string Description
            {
                get { return description; }
                set { description = value; }
            }
        }
    }
}